package com.itcast.netty.client;

import com.itcast.netty.utils.ChannelUtils;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPromise;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * 通道适配器
 *
 * @author eternity
 */
@Slf4j
public class NettyClientHandlerAdapter extends ChannelHandlerAdapter {

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("{} -> [通道异常] {}", this.getClass().getName(), ctx.channel().id());
        ChannelUtils.remove(ctx.channel());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("{} -> [连接建立成功] {}", this.getClass().getName(), ctx.channel().id());
        // 注册通道
        ChannelUtils.registerChannel(ctx.channel());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        log.info("{} -> [客户端收到消息] {}", this.getClass().getName(), msg);
        String text = ctx.channel().id().asLongText();
        String resultText = ChannelUtils.getResultKey(text);
        ChannelUtils.calculateResult(resultText, msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        log.info("{} -> [客户端读取完毕] {}", this.getClass().getName(), ctx.channel().id());
        super.channelReadComplete(ctx);
        boolean active = ctx.channel().isActive();
        log.info("{} -> [此通道状态] {}", this.getClass().getName(), active);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.info("{} -> [客户端心跳监测发送] 通道编号: {}", this.getClass().getName(), ctx.channel().id());
        if (evt instanceof IdleStateEvent) {
            ctx.writeAndFlush("ping-pong-ping-pong");
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
        log.info("{} -> [关闭通道] {}", this.getClass().getName(), ctx.channel().id());
        super.close(ctx, promise);
    }
}
